package java学习.第17章_反射机制;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 *
 * 反射相关的主要API
 *   ●java.lang.Class:代表一个类
 *   ●java.lang.reflect.Method:代表 类的方法
 *   ●java.lang.reflect.Field:代表 类的成员变量
 *   ●java.lang.reflect.Constructor:代表类的构造器
 *
 * 单例模式 就不行了，使用反射可以调用，
 *
 * 是否和封装性冲突，是不是 Java语言存在bug
 * 封装性：提示是否建议我们调用
 * 反射：谁否能调用
 *
 */
public class B_反射的基本使用 {
    @Test
    public void 正常调用(){
        FS fs = new FS();
        fs.age=1;
        fs.getAge();
    }
    /**
     * get//获取
     * Declared//声明的    加个这  可以获取私有的
     *              给个这   .setAccessible(true);   可以调用私有的
     * Field//属性
     * Method//方法
     * Constructor//构造器
     * Instance   实例
     * invoke    援引    调用方法
     */
    @Test
    public void 反射基本调用() throws Exception{
            Class<FS> fsClass = FS.class;
        //调用构造器
        FS fs = fsClass.newInstance();//无参构造  已废弃
        fs = fsClass.getDeclaredConstructor().newInstance();//推荐

        System.out.println(fs);

        //调用属性
        Field age = fsClass.getField("age");
        age.set(fs,10);
        System.out.println(age.get(fs));

        //调用方法
        Method pu = fsClass.getMethod("pu");
        pu.invoke(fs);

    }
    @Test
    public void 私有的调用() throws Exception{
        Class<FS> fsClass = FS.class;

        //调用私有构造器
        Constructor<FS> conFs = fsClass.getDeclaredConstructor(String.class, int.class);
        conFs.setAccessible(true);//使其可以调用私有的信息
        FS fs = conFs.newInstance("Tom", 12);
        System.out.println(fs);

        //调用私有属性
        Field name = fsClass.getDeclaredField("name");
        name.setAccessible(true);
        name.set(fs,"张三");
        System.out.println(fs);

        //调用私有方法
        Method show = fsClass.getDeclaredMethod("show", String.class);
        show.setAccessible(true);
        Object ch = show.invoke(fs,"中国");
        System.out.println("返回值：" + ch);
    }
}
